﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GestureLib;
using System.Windows;
using System.Windows.Media.Animation;
using System.Timers;

namespace GestureLibDemo
{
    class ShakeWindowAnimatedAction : IGestureAction
    {
        [Flags()]
        public enum ShakeDirection
        { 
            Horizontal = 1, 
            Vertical = 2
        }

        delegate void ChangeTopDelegate(double top);
        delegate void ChangeLeftDelegate(double left);

        public ShakeWindowAnimatedAction()
        {
            MaxLoops = 20;
            VerticalDifference = 20;
        }

        private void ChangeTop(double top)
        {
            if (Window.Dispatcher.CheckAccess())
            {
                Window.Top += top;
            }
            else
            {
                Delegate dlg = new ChangeTopDelegate(ChangeTop);
                Window.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, dlg, top);
            }
        }
        private void ChangeLeft(double left)
        {
            if (Window.Dispatcher.CheckAccess())
            {
                Window.Left += left;
            }
            else
            {
                Delegate dlg = new ChangeTopDelegate(ChangeLeft);
                Window.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, dlg, left);
            }
        }

        private void Animate()
        {
            bool down = false;
            int currentLoop = 0;
            Timer timer = new Timer(20);

            timer.Start();

            timer.Elapsed += new ElapsedEventHandler(
                delegate(object sender, ElapsedEventArgs e)
                {
                    down = !down;

                    if (down)
                    {
                        if((Direction & ShakeDirection.Vertical) == ShakeDirection.Vertical)
                            ChangeTop(VerticalDifference);

                        if ((Direction & ShakeDirection.Horizontal) == ShakeDirection.Horizontal)
                            ChangeLeft(VerticalDifference);
                    }
                    else
                    {
                        if ((Direction & ShakeDirection.Vertical) == ShakeDirection.Vertical)
                            ChangeTop(-VerticalDifference);

                        if ((Direction & ShakeDirection.Horizontal) == ShakeDirection.Horizontal)
                            ChangeLeft(-VerticalDifference);
                    }

                    currentLoop++;

                    if (currentLoop > MaxLoops)
                    {
                        timer.Stop();
                        timer.Dispose();
                    }
                });
        }

        #region IGestureAction Members

        public void Execute()
        {
            Animate();
        }

        #endregion

        #region INamed Members

        public string Name { get; set; }

        #endregion

        public Window Window { get; set; }
        public int MaxLoops { get; set; }
        public int VerticalDifference { get; set; }
        public ShakeDirection Direction { get; set; }
    }
}
